Published by Saif on Saturday 11 May 2024 17:03
The paella must be possibly the worst national dish ever created, I thought to myself as I looked at the charred remains in my pan. It is as if the mind of some ancient Spanish conquistador, returned from his conquests abroad feeling hungry and unfulfilled, dreamt of bringing byriani to Spain, but in the midst of pillaging had forgotten to take culinary notes.
"How difficult can it be, Jose?" the weary warrior muses,
"Yeah, yeah, its just rice and meat, innit", says his Catalan colleague coming from the Spanish equivalent of Birmingham.
"We could use something flavourless, amorphous and chewy, like mussels, instead of meat",
"Whoaaah, nice,",
"And langoustines...",
"langa-what?",
"I know, right? Just throw them all in, don't bother shelling them",
"Raphael has some tomatoes he doesn't need for pelting passing pedestrians",
"Ahh...the flavours", fanning the flames as the smell of their concoction cooking brings back fond memories of far-away burning villages.
As I proudly presented my still smouldering efforts on the table, I am met with quizzical glances.
"What is it?" asked Mrs Saif, "I mean I can see what it is, but what is meant to be?",
"Its Spanish! Paella!", I exclaimed, "It's what Nadal, Ballesteros, and Ronaldo eat, guys. Come on, tuck in!",
The kids were not too sure, "Looks like your byriani" said one, encouragingly.
"Ronaldo is Portuguese," said another hoping to distract while passing her food to the dog who knew better.
"Look, why don't we order Mexican" said Mrs Saif kindly, "and you can try something you are goo.. err.. not so bad at."
Failure, I am used to. Under appreciation, I accept as the condemned accepts the noose. If I can divert my attention to coding instead of cooking, I may perhaps have less cause for despondency. But for me, the two streams of activity, cooking or coding, have the same triggers, and very often the same outcomes. Some one says: "You can't cook", outcome: paella. "You can't do this in Perl", outcome: more burnt offerings, sacrificing time and sanity, yielding an unrecognisable, unconsumable concoction for presentation to a community that never wanted it in the first place.
So when one person on Reddit presented a gist to use bash
, ncal
and Perl to create a week counting calendar on a terminal,
I thought, hey this could be done in Perl alone.
What's the point?
Here-in lies the problem with the irresponsible, belligerent coder, unsatisfied with mere re-implementation of another's code, who has to add his own flavours into the profusion of existing successful recipes. After all, MetaCPAN has no shortage of Calendar Modules, including Manwar's collection of excellent exotic calendars.
I have started yet another project, this time a Calendar Application for the Terminal,
which will (eventually) be interactive, customisable, use terminal colours for highlighting, allow adding and removing of events, will import, export and use standard .ics
files, and create crontab
lines. Or it might end up an exercise that once again reveals how inadequacies overcome aspirations.
Similar things exist (CalCurses, uses curses library) and
(khal in Python) as well as cal
and ncal
, for those interested in such tools. Of course, I know my limitations, and this project will be Pure Perl. Pure Madness. Of course, if someone gets the title of this blog, somehow, it will prove to me that there are such other mad people around.
Published by /u/Adriaaaaaaaan on Saturday 11 May 2024 11:27
submitted by /u/Adriaaaaaaaan [link] [comments] |
Published by Bernd Wechner on Saturday 11 May 2024 07:40
I'm trying to make a substitution in a file with a one liner regex. sed failed me so I turned to perl. I can for example match "setting = value # comment" and extract it in three parts "setting = ", "value" and " # comment".
For example:
perl -lne 'print "-1-$1-2-$2-3-$3-E-" if /^\s*(setting\s*=\s*)([^\s#]+)(\s*#\s*.*)?/'
and I'll see a result like -1-setting = -2-value-3- # comment-E-
Now the problem emerges that value might be wrapped in quotes, whether single or double, the simple '
or '"
character. Unbiased, same in the opening and closing form.
It's tempting to use a backreference to detect matching quotes:
perl -lne 'print "-1-$1-2-$2-3-$3-4-$4-5-$5-E-" if /^\s*(setting\s*=\s*)(\N{APOSTROPHE}|\N{QUOTATION MARK})?([^\s#]+)(\2)?(\s*#\s*.*)?/'
The problem here is that group 3 captures the closing quotation and group 4 is empty.
And here we run into a problem. We cannot add the backreference to the negative assertion for group 3, perl doesn't support that for the simple reason that the capture group is not a character (or not guranteed to be one, even though ours is).
So this raises a conundrum. Is there a way to catch these optional matching quotes in a perl regex?
My thinking and reading and experimentation thus far led me to consider the possibility of:
A negative assertion on strings not characters. We have [abc]
which matches a, b or c, and we have [^abc]
matching any charcater that is not a, b or c, and we have (string1|string2|string3)
which matches any of string1, string2, or string3. But is there a negative form of that assertion, any strig that is not string1, string2, or string3?
Creating a character group, a capture group of one character that can be used in a backreference in a negative character set?
Referencing one character in a backreference, like the first character.
Referring to a backreference as a set of characters not a string ... for inclusion in the negative set.
Using a look around assertion. Alas, we have look behind and look ahead but not look at.
Maybe this is too hard for a regex?
Published by Joseph White on Friday 10 May 2024 18:05
PERL: Test::Simple, Time::HiRes, and Test::Harness, and Test::Deep and Devel-CheckLib have cirular dependencies. How to resolve them?
MakeMaker was the source of some of the problems. One of the tests failed. I simply had to install to get MM available for the other packages. But these other packages had dependencies on one another.
I am getting @include errors because the modules aren't available. Usually that means add a path to $PERL5Lib or $LD_LIBRARY_PATH, but the modules aren't installed yet.
The tests return messages like these:
t/Legacy/overload.t .............................. Dubious, test returned 2 (wstat 512, 0x200) No subtests run t/Legacy/overload_threads.t ...................... Dubious, test returned 2 (wstat 512, 0x200) No subtests run t/Legacy/plan.t .................................. Dubious, test returned 2 (wstat 512, 0x200) No subtests run
All fail. It may be due to @include errors--that's usually why the tests fail in my experience.
How should I resolve these dependencies?
On this site: https://codegolf.stackexchange.com/questions/246845/convert-json-object-of-directories-to-list-of-paths
There is an interesting perl solution but I'm trying to wrap my head around it and am baffled.
map/}/?/{/&&say($s)..$s=~s|[^/]+/$||:($s.=s/"//gr."/"),/{?}|".+?"/g When I do a simple test: my $s = <some json string> .. the map above I don't get any output. Thanks in advance
I have a bunch of files that I am parsing out a simple tag
<institution content-type="division">(.+?)?<\/institution>
Everything is going fine until I hit this result:
2) School of Chemical & Biomolecular Engineering
This is complaining because it thinks the ) is unmatched. How do I get it to accept whatever is in the capture? I tried playing around with \Q and \E but that isn't working. For clarity, I won't know what is in this tag, it could be anything at all and the tag is simple enough that I don't want to use some XML parser.
Published by Colin Brett on Friday 10 May 2024 12:06
$combatblock = "$name:$dex:$db:$mp:$hp";
I'm using Perl 5.36 on Debian Linux 12 and am writing a utility for a roleplaying game. This isn't a work-related project, as I'm more of a hobbyist than a serious programmer, so I apologise if this isn't really an appropriate request.
My input file looks like this:
Name: orc of power normal
mw_monsters normal
Stats: STR [14] CON [10] SIZ [10] INT [8] POW [8] DEX [15] APP [8] EDU [5]
SCB: Physical=7 Communication=4 Knowledge=4 Manipulation=8 Perception=5
Combat: Hit Points=10 Major Wound Level=5 Armour=
Initiative:
Stat Rolls: Effort 70% Stamina 50% Idea 40% Luck 40% Agility 75% Charisma 40% Know 25%
Derived: MP=8 XP=4 FP=24 SAN=40% DB=NONE MOV [10]
Skills: Scimitar 42% Composite Bow 42% Short Spear 42% Short Spear (thrown) 42% Spiked Shield 42% Climb 62% Dodge 47% Hide 42% Lore (Orc-lore) 39% Language (Human) 29% Language (Orcish) 64% Ride (warboar) 57% Sense 40% Search 50% Move Quietly 47% Track 35%
++ Distribute 40% to ONE skill and 20% to THREE skills
Powers:
This orc is not a sorcerer.
Possessions:
Notes:
I want to select certain parts of these lines and produce output like this:
Name:DEX:DB:MP:HP:Current:
orc:[15]:DB=NONE:MP=8:Points=10
This is my code so far:
#!/usr/bin/env perl
use strict;
use warnings;
my $line;
my $combatblock = "";
my $name = "";
my $dex = "";
my $db = "";
my $mp = "";
my $hp = "";
my @combatarray;
my @nameline;
my @statline;
my @hpline;
my @derivedline;
print "Name:DEX:DB:MP:HP:Current:\n";
while ($line = <>) {
chomp $line;
if ($line =~ "Name") {
@nameline = split (/ /,$line);
$name=$nameline[1]; # Name
};
if ($line =~ "STR") {
@statline = split (/ /,$line);
$dex=$statline[12]; # DEX for initiative
};
if ($line =~ "Derived") {
@derivedline = split (/ /,$line);
$db=$derivedline[5]; # Damage Bonus
$mp=$derivedline[1]; # Magic Points
};
if ($line =~ "Hit Points") {
@hpline = split (/ /,$line);
$hp=$hpline[2]; # Hitpoints
};
$combatblock = "$name:$dex:$db:$mp:$hp";
print "$combatblock\n"; # This can be commented out to get rid of unnecessary output
};
print "Result $combatblock\n"; # Result can be taken out of this line
What it generates is this:
61 colin@kuu> combatstatblock.pl < orc.txt
Name:DEX:DB:MP:HP:Current:
orc::::
orc::::
orc:[15]:::
orc:[15]:::
orc:[15]:::Points=10
orc:[15]:::Points=10
orc:[15]:::Points=10
orc:[15]:DB=NONE:MP=8:Points=10
orc:[15]:DB=NONE:MP=8:Points=10
orc:[15]:DB=NONE:MP=8:Points=10
orc:[15]:DB=NONE:MP=8:Points=10
orc:[15]:DB=NONE:MP=8:Points=10
orc:[15]:DB=NONE:MP=8:Points=10
orc:[15]:DB=NONE:MP=8:Points=10
Result orc:[15]:DB=NONE:MP=8:Points=10
62 colin@kuu>
Now, I understand this is actually doing what it's written to do. As noted in a comment string above, I can take out "print "$combatblock\n";
" to get rid of all the other output and just leave the "Result" line.
This script is supposed to process many more "orc" stats and produce output like this:
Name:DEX:DB:MP:HP:Current:
orc:[15]:DB=NONE:MP=8:Points=10
orc:[19]:DB=NONE:MP=13:Points=10
orc:[12]:DB=+1D4:MP=10:Points=12
... and so on through the input file.
What's happening is that only the last result (orc:[12]
in this case) is printed: the while loop overwrites the previous value of $combatblock
.
How can I break out of the while loop, print the "Result" line, then go back to the top of the while loop to process the next set of "orc" stats?
I've tried:
"if ($line =~"
statements inside another foreach or while loop@combatarray
structure to push the $combatblock
onto$combatblock
inside the "if
" statements with lines like "$combatblock = "$combatblock:$db:$mp:""
(which are commented out in the script above)Nothing seems to get past the "while overwrites the previous value" problem. I'm pretty sure the solution is quite simple but I simply can't find a way forward.
Any help would be greatly appreciated.
submitted by /u/oalders [link] [comments] |
Published by LEX-DOCTOR APLICACIONES on Friday 10 May 2024 00:09
This is part of a perl script used for years for downloading files via http. Now it still download the files, but it seems the Content-length field cannot be readed by the http client (chrome, edge or firefox tested); so the progress bars are doing a marquee instead of a progress.
$file = "$ENV{DOCUMENT_ROOT}$dir/$arch";
$len = -s $file;
print "Content-Type:application/octet-stream\n";
print "Content-Disposition:attachment;filename=$arch\n";
print "Content-Length:$len\n\n";
open FILE, "< $file" or Error('Cannot read '.$arch);
binmode FILE;
local $/ = \32768;
while (<FILE>){
print $_;
};
close FILE;
Somebody know why this behaviour changed?
Published by Perl Steering Council on Thursday 09 May 2024 20:29
Just Graham and Paul
Aside from that, things are looking good for making a 5.40 release at the usual schedule in May.
Published by russbrewer on Thursday 09 May 2024 19:46
I recently set up a virtual Server Running Rocky Linux 9 as a client from which to query a remote MariaDB database. I used perlbrew to install Perl 5.38.2. I installed client related RPMs for MariaDB 10.5, I installed DBIx::Class as a relational mapper that can create Perl Schema Result Classes for each table in the database. If you are new to DBIx::Class, you can review its purpose and features in DBIx::Class::Manual::Intro. The Result Classes used by Perl to query the database are stored on the client server in a schema directory. They are created with the DBIx::Class::Schema::Loader module.
I only work with databases as a home hobbyist, but I have successfully used DBIx::Class and related DBIx::Class::Schema::Loader from a CentOS 7 server running Perl 5.24.1 with MariaDB 5.5 client related RPMs. My intent was to replace a CentOS 7 virtual server with a Rocky 9 virtual server and upgrade from MariaDB 5 client to a MariaDB 10 client.
The CentOS 7 client used DBD::mysql which works fine with MariaDB 5 but would not install on the Rocky server which used MariaDB 10 RPMs. So I installed DBD::MariaDB and DBIx::Class::Storage::DBI::MariaDB on the client Rocky server.
To create my relationship classes, I ran the schema loader and was surprised that DBIx::Class::Schema::Loader did not produce correct Result Classes on the Rocky 9 server. Later I found that it did not work properly a on Rocky 8 server either. The common issue was MariaDB version 10 compatibility with DBIx::Class::Schema::Loader (and its dependencies).
I am not sure of everything that was wrong with the Result Classes, but the obvious problems were missing the primary keys entries, missing auto_increment entries and missing unsigned integer entries for all Result Classes which should have them.
I found the problem described (but not resolved) in November 2023 in this short Perl Monks thread.
Below I describe the steps I took to get DBIx::Class::Schema::Loader and its dependencies to produce Result Classes on the MariaDB 10 client (Rocky 8 and 9) servers that was identical to that being produced on the MariaDB 5 client CentOS 7 server, remembering that all of them where creating the Result Classes by connecting to the same remote database server. Although not significant for this issue, the remote database was running smoothly on a Rocky 8 server using MariaDB 10.3.
First I noticed that the DBIx/Class/Schema/Loader/DBI directory had a mysql.pm file but had no MariaDB.pm counterpart. So I made a copy of mysql.pm named MariaDB.pm and then I edited the new MariaDB.pm file to change references to mysql and MySQL to MariaDB. Note that almost all the edits can use MariaDB as the substitute for mysql and MySQL but entries in the "_extra_column_info
" subroutine must use lowercase "mariadb
". This is because they refer to lowercase terminology expected by DBD::MariaDB as can be seen in site_perl/5.38.2/x86_64-linux/DBD/MariaDB.pm.
In DBIx/Class/Schema/Loader/DBI/MariaDB.pm, for subroutine "_extra_column_info
", keep references to mariadb in lowercase. For example:
mysql_is_auto_increment
should become mariadb_is_auto_increment
$dbi_info->{mysql_type_name}
should become $dbi_info->{mariadb_type_name}
In all other cases I used MariaDB (not mariadb) as the substitution.
I then realized that DBIx::Class::Schema::Loader depends on DBI::Class::SQLMaker which supports a number of dependent modules such as MySQL.pm, MSSQL.pm, SQLite.pm and Oracle.pm, but did not have a corresponding MariaDB.pm file. So I made a copy of MySQL.pm named MariaDB.pm and then I edited the new MariaDB.pm file to change references to mysql and MySQL to MariaDB.
After the edits, the Schema loader started working correctly in that running Schema Loader created Schema Result Classes that matched the output of the older MariaDB 5 client.
Although apparently not directly related to the functioning of DBIx::Class::Schema:Loader, there are several other files that might need similar editing to provide full MariaDB functionality via DBIx::Class. Your Perl version may differ, but for me these modules are:
The directories contain references to other database types but do not provide a MariaDB.pm file. Inside each of the above directories, I copied the mysql.pm file and named it MariaDB.pm. Then I edited each new MariaDB.pm file to change mysql and MySQL entries to MariaDB entries. These additional MariaDB.pm files are not required to get the loader to simply create the Schema Result Classes from a database. I need to test to see what effect adding the MariaDB.pm files to these directories has on DBIx::Class functionality.
The following two files make internal references to mysql or MySQL but did not have a reference to MariaDB. Therefore, I edited each file:
For file DBIx/Class/Storage/DBI/MariaDB.pm, which is provided from CPAN, in subdirectory sqlt_type, edit to return 'MariaDB'
instead of returning 'MySQL'
.
Also change this line:
__PACKAGE__->sql_maker_class('DBIx::Class::SQLMaker::MySQL');
to this line:
__PACKAGE__->sql_maker_class('DBIx::Class::SQLMaker::MariaDB');
In the Utils.pm file there is a subroutine named ‘parse_mysql_version
’. Copy this subroutine, and name it ‘parse_MariaDB_version’. Then edit subroutine parse_MariaDB_version
to change references to MariaDB instead of MySQL. Finally, edit the Export_OK entry to include parse_MariaDB_version
.
After making the essential edits I was able to produce Schema Result Classes that appear to be accurate and not missing information. After making the additional edits the Schema Loader still worked correctly.
I have not been able to do production level testing on these changes. I suspect the additional edits and some as yet unidentified edits are needed for full DBIx::Class functionality with MariaDB 10. For example, version control for using the Schema to modify the database (instead of reading the database to create the schema) is probably not working.
I have only tested the schema result class build with a command such as:
use DBIx::Class::Schema::Loader qw/ make_schema_at /;
make_schema_at(
'MyApp::Schema',
{
debug => 1,
dump_directory => './lib/test',
create => 'static',
components => [ 'TimeStamp' ]
},
[
'dbi:MariaDB:database=database_name;host=192.168.xxx.xxx', 'username',
'secret_pw', { AutoCommit => '1' }
],
);
My criterion for success was that (after just the essential edits) the MariaDB 10 clients (on my Rocky 8 and 9 servers) produced identical schema result classes as my MariaDB 5 client running on my CentOS 7 server when querying the same Maria 10 database.
My target database consists of 46 tables containing an assortment on foreign keys defining has_many, belongs_to and many_to_many relationships. The tables contain unsigned integers, unique keys, combined primary keys, auto_increment, integers (signed and unsigned), timestamp, NULLS and not_NULLS, char, varchar, and text data types.
This information is part of a work in progress and my testing is not yet complete. Use these changes at your own risk. They are offered without warranty. You should test thoroughly before incorporating them in important work. Generate your test schemas to a separate directory to avoid harming a known good schema.
If you can provide additional information, corrections and improvements, please share them.
Published by Makoto Nozaki on Thursday 09 May 2024 19:21
TL;DR We just finished intern selection for this year’s Outreachy program. We got more projects and more applicants than the previous years, which made the selection hard in a good way.
Continuing our annual tradition, The Perl and Raku foundation is involved in the Outreachy program which provides internships to people subject to systemic bias and impacted by underrepresentation.
We have just finished the intern selection process, which turned out to be harder compared to the previous years. I’ll explain the reasons below.
Each year, we call for project ideas from the Perl/Raku community. Project proposer is required to commit to mentoring an intern from May to August. Given the significant commitment involved, it’s not uncommon for us to find suitable projects.
Fortunately, this year, we got two promising project proposals. The Foundation’s financial situation did not allow us to sponsor both projects, so we had to make the tough decision to support only one project.
After careful consideration, the Board has elected to sponsor Open Food Fact’s Perl project, titled “Extend Open Food Facts to enable food manufacturers to open data and improve food product quality.”
Having more projects means we were able to attract more intern candidates. Across the two projects, more than 50 people showed interest and initiated contributions. Among them, 21 individuals actually created pull requests before the selection process.
Needless to say, it's hard work for the mentors to help dozens of candidates. They taught these intern candidates how to code and guided them through creating pull requests. On the applicants’ side, I am amazed that they worked hard to learn Perl and became proficient enough to create pull requests and make real improvements to the systems.
After the contribution process, we got an application from 14 people. It was obviously hard for the mentors to select one from so many good applicants. In the next post, Stéphane Gigandet will introduce our new intern to the community.
I wish all the best to the mentors, Stéphane and Alex, and our new intern.
"In the journey to understand Perl better, I wanted to know what are its most wide applications, one of them being a web scraper. It's because Perl's strong support for regular expressions and built-in text manipulation functions make it well-suited for tasks like web scraping, where parsing and transforming text are essential. I took inspiration from various web scraping projects available on the internet to gain insights into the process and developed a lyrics scraper."
"I'm currently diving into Perl, and I see this as a fantastic chance to enrich my coding skills. I've thoroughly enjoyed immersing myself in it and have had the opportunity to explore various technologies like Docker and more."
"I have had the opportunity to experience Perl firsthand and have come to appreciate its significance in web development, on which I have worked. During my second year, I was searching for popular languages in backend development and found out about Perl, whose syntax was somewhat like C and Python. I didn't have any previous experience working with Perl, but now I have gained a deep understanding of its importance and impact on backend development and data processing."
"In this pull request, I made a significant stride in improving the quality and maintainability of our Perl codebase by integrating Perl::Critic, a powerful static code analysis tool."
"I've learned a whole lot about Perl and some of its frameworks such as Dancer2 (a surprisingly simple framework I've come to fall in love with)."
Welcome to “What’s new on CPAN”, a curated look at last month’s new CPAN uploads for your reading and programming pleasure. Enjoy!
Published by Kwabena on Thursday 09 May 2024 18:39
I am using the perl XML::LibXML module to manipulate an XML file.
I want to remove the opening and closing tags of an XML node if it has a certain attribute, making its text and subnodes as a part of the parent of the node.
Here's an unsuccessful attempt. If fails with a insertBefore/insertAfter: HIERARCHY_REQUEST_ERR
:
#!/usr/bin/env perl
use 5.020;
use warnings;
use XML::LibXML;
#the input xml
my $inputstr = <<XML;
<root>
<a>
<b class="deletethistag">keep this text<c>keep this c node</c>keep this text too</b>
<b class="someothertag">don't change this</b>
<b>don't change this node without an attribute</b>
<c class="type1">don't change this either</c>
</a>
</root>
XML
my $desiredstr = <<XML ;
<root>
<a>keep this text<c>keep this c node</c>keep this text too
<b class="someothertag">don't change this</b>
<b>don't change this node without an attribute</b>
<c class="type1">don't change this either</c>
</a>
</root>
XML
my $dom = XML::LibXML->load_xml(
string => $inputstr
);
# Convert $inputstr to $desiredstr *** doesn't work ***
foreach my $node ($dom->findnodes(q#//a/b[@class="deletethistag"]/*#)) {
my $nodestring = $node->toString(1);
say STDERR $nodestring;
my $replacementnode = XML::LibXML->load_xml(string => $nodestring);
$node->parentNode()->insertAfter($replacementnode, $node);
$node->unbindNode();
}
say $dom->toString(1);
I want to use the code to remove <span lang="en" xml:space="preserve">...</span>
markup from a file, but I have framed it as a more general question so that I understand more of the details of working with XML::LibXML.
Published by /u/leonerduk on Thursday 09 May 2024 15:29
Published by mauke on Thursday 09 May 2024 05:11
Fcntl: add module documentation
Published by laurent_r on Wednesday 08 May 2024 22:43
These are some answers to the Week 268, Task 2, of the Perl Weekly Challenge organized by Mohammad S. Anwar.
Spoiler Alert: This weekly challenge deadline is due in a few days from now (on May 12, 2024 at 23:59). This blog post provides some solutions to this challenge. Please don’t read on if you intend to complete the challenge on your own.
You are given an array of integers, @ints
, with even number of elements.
Write a script to create a new array made up of elements of the given array. Pick the two smallest integers and add it to new array in decreasing order i.e. high to low. Keep doing until the given array is empty.
Example 1
Input: @ints = (2, 5, 3, 4)
Output: (3, 2, 5, 4)
Round 1: we picked (2, 3) and push it to the new array (3, 2)
Round 2: we picked the remaining (4, 5) and push it to the new array (5, 4)
Example 2
Input: @ints = (9, 4, 1, 3, 6, 4, 6, 1)
Output: (1, 1, 4, 3, 6, 4, 9, 6)
Example 3
Input: @ints = (1, 2, 2, 3) Output: (2, 1, 3, 2)
In Raku, a for
loop using a pointy block syntax can use two (or more) parameters, as shown with three block parameters in the Raku REPL example below:
> for 1..9 -> $a, $b, $c { say "$a, $b and $c" }
1, 2 and 3
4, 5 and 6
7, 8 and 9
We use this feature to pick up and reverse two items at a time of the input array:
sub number-game (@in) {
my @result;
for @in.sort -> $i, $j {
push @result, $j, $i;
}
return @result;
}
my @tests = <2 5 3 4>, <1 1 4 3 6 4 9 6>, <1 2 2 3>;
for @tests -> @test {
printf "%-16s => ", "@test[]";
say number-game @test;
}
This program displays the following output:
$ raku ./number-game.raku
2 5 3 4 => [3 2 5 4]
1 1 4 3 6 4 9 6 => [1 1 4 3 6 4 9 6]
1 2 2 3 => [2 1 3 2]
Perl doesn't have the Raku syntax with several parameters, but we can easily simulate it with two shift
statements, as shown in the code below:
use strict;
use warnings;
use feature 'say';
sub number_game {
my @in = sort { $a <=> $b } @_;
my @result;
while (@in) {
my $i = shift @in;
my $j = shift @in;
push @result, $j, $i;
}
return join " ", @result;
}
my @tests = ([<2 5 3 4>], [<1 1 4 3 6 4 9 6>], [<1 2 2 3>]);
for my $test (@tests) {
printf "%-16s => ", "@$test";
say number_game @$test;
}
Note that this code could be made significantly shorter using a splice
statement:
sub number_game {
my @in = sort { $a <=> $b } @_;
my @result;
push @result, reverse splice @in, 0, 2 while @in;
return join " ", @result;
}
This program displays the following output (both versions):
$ perl ./number-game.pl
2 5 3 4 => 3 2 5 4
1 1 4 3 6 4 9 6 => 1 1 4 3 6 4 9 6
1 2 2 3 => 2 1 3 2
The next week Perl Weekly Challenge will start soon. If you want to participate in this challenge, please check https://perlweeklychallenge.org/ and make sure you answer the challenge before 23:59 BST (British summer time) on May 19, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.
Published by laurent_r on Wednesday 08 May 2024 19:32
These are some answers to the Week 268, Task 1, of the Perl Weekly Challenge organized by Mohammad S. Anwar.
Spoiler Alert: This weekly challenge deadline is due in a few days from now (on May 12, 2024 at 23:59). This blog post provides some solutions to this challenge. Please don’t read on if you intend to complete the challenge on your own.
You are given two arrays of integers of same size, @x
and @y
.
Write a script to find the magic number that when added to each elements of one the array gives the second array. Elements order is not important.
Example 1
Input: @x = (3, 7, 5)``
@y = (9, 5, 7)
Output: 2
The magic number is 2.
@x = (3, 7, 5)
+ 2 2 2
@y = (5, 9, 7)
Example 2
Input: @x = (1, 2, 1)
@y = (5, 4, 4)
Output: 3
The magic number is 3.
@x = (1, 2, 1)
+ 3 3 3
@y = (5, 4, 4)
Example 3
Input: @x = (2)
@y = (5)
Output: 3
We should first notice that it is possible that there is no solution. In fact, with random input, the probability is high that there will be no solution, and I believe we should consider this case. In both my implementations (Raku and Perl) below, I have added one such case to the examples provided with the task.
The task specifies that elements order is not important. But any solution will rely on the order being the same, either ascending or descending (or some other custom order). So we will sort the input arrays and compare the items pairwise.
In the following Raku implementation, we sort the items and build an array (@gaps
) of the pairwise differences between the sorted items. We have a solution if all the pairwise differences are equal, which we find out using the [==]
reduction meta-operator.
sub magic-nr (@x, @y) {
my @in1 = @x.sort; `
my @in2 = @y.sort; ] `
my @gaps = map {@in1[$_] - @in2[$_]}, 0..@x.end;
return Nil unless [==] @gaps;
return @gaps[0].abs;
}
my @tests = (<3 7 5>, <9 5 7>), (<1 2 1>, <5 4 4>),
((2,), (5,)), (<3 7 5>, <6 5 7>);
for @tests -> @test {
printf "%-6s - %-6s => ", "@test[0]", "@test[1]";
say magic-nr @test[0], @test[1];
}
This program displays the following output:
$ raku ./magic-numbers.raku
3 7 5 - 9 5 7 => 2
1 2 1 - 5 4 4 => 3
2 - 5 => 3
3 7 5 - 6 5 7 => Nil
Our Perl implementation will be slightly different and, we hope, slightly more efficient in some failure cases: we don't need to compute and compare all items, we can stop the iteration as soon as we find a mismatch.
use strict;
use warnings;
use feature 'say';
sub magic_nr {
my @in1 = sort {$a<=>$b} @{$_[0]};
my @in2 = sort {$a<=>$b} @{$_[1]};
my $gap = $in1[0] - $in2[0];
for my $i (1..$#in1) {
return "undef" if $in1[$i] - $in2[$i] != $gap;
}
return abs $gap;
}
my @tests = ([[<3 7 5>], [<9 5 7>]], [[<1 2 1>], [<5 4 4>]],
[[2,], [5]], [[<3 7 5>], [<6 5 7>]] );
for my $test (@tests) {
printf "%-6s - %-6s => ", "@{$test->[0]}", "@{$test->[1]}";
say magic_nr $test->[0], $test->[1];
}
This program displays the following output:
$ perl ./magic-numbers.pl
3 7 5 - 9 5 7 => 2
1 2 1 - 5 4 4 => 3
2 - 5 => 3
3 7 5 - 6 5 7 => undef
The next week Perl Weekly Challenge will start soon. If you want to participate in this challenge, please check https://perlweeklychallenge.org/ and make sure you answer the challenge before 23:59 BST (British summer time) on May 19, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.
Published by alh on Monday 06 May 2024 19:42
Tony writes:
``` [Hours] [Activity] 2024/02/01 Thursday
2.50
2024/02/02 Friday 0.72 #21915 review, testing, comments
0.97
2024/02/05 Monday 0.25 github notifications 0.08 #21885 review updates and approve 0.57 #21920 review and comment 0.08 #21921 review and approve 0.12 #21923 review and approve 0.08 #21924 review and approve 0.08 #21926 review and approve 0.67 #21925 review and comments
3.93
2024/02/06 Tuesday 0.23 #21925 comment 0.52 review coverity scan report, reply to email from jkeenan 0.27 #21927 review and comment 0.08 #21928 review and approve
1.18
2024/02/07 Wednesday 0.25 github notifications 0.52 #21935 review, existing comments need addressing
2.89
2024/02/08 Thursday 0.40 #21927 review and approve 0.23 #21935 review, check each comment has been addressed, approve 0.45 #21937 review and approve 0.15 #21938 review and comment 0.10 #21939 review and approve 0.13 #21941 review and approve 0.10 #21942 review and approve 0.08 #21943 review and approve 0.07 #21945 review and approve 0.17 #21877 look into CI failures, think I found problem, push probable fix 0.18 #21927 make a change to improve pad_add_name_pvn() docs, testing, push for CI 2.20 #21877 performance test on cygwin, try to work up a
4.26
2024/02/12 Monday 0.60 #18606 fix minor issue pointed out by mauke, testing 0.40 github notifications 0.08 #21872 review latest changes and approve 0.08 #21920 review latest changes and approve 1.48 #21877 debugging test 0.30 #21524 comment on downstream ticket
3.21
2024/02/13 Tuesday 0.35 #21915 review, brief comment 0.25 #21983 review and approve 0.03 #21233 close 0.28 #21878 comment 0.08 #21927 check CI results and make PR 21984 0.63 #21877 debug failing CI 0.27 #21984 follow-up 0.58 #21982 review, testing, comments
2.79
2024/02/14 Wednesday 1.83 #21958 testing, finally reproduce, debugging and comment 0.08 #21987 review discussion and briefly comment 0.08 #21984 apply to blead 0.22 #21977 review and approve 0.12 #21988 review and approve 0.15 #21990 review and approve 0.82 #21550 probable fix, build tests 0.38 coverity scan follow-up 1.27 #21829/#21558 (related to 21550) debugging
5.60
2024/02/15 Thursday 0.15 github notifications 0.08 #21915 review updates and approve 2.17 #21958 debugging, research, long comment 0.58 #21958 testing, follow-up
3.10
2024/02/19 Monday 0.88 #21161 review comment and reply, minor change, testing, force push 0.23 #22001 review and comment 0.30 #22002 review and comment 0.12 #22004 review and comment 0.28 #22005 review and approve 0.32 #21993 testing, review changes 1.95 #21661 review comments on PR and fixes, review code and
4.08
2024/02/20 Tuesday 0.35 github notifications 0.08 #22010 review and approve 0.08 #22007 review and approve with comment 0.60 #22006 review, research and approve with comment 0.08 #21989 review and approve 0.58 #21996 review, testing, comment 0.22 #22009 review and approve 0.50 #21925 review latest updates and approve
3.54
2024/02/21 Wednesday 0.18 #22011 fixes 0.80 #21683 refactoring
2.78
2024/02/22 Thursday 0.38 #22007 review and comment 0.70 #21161 apply to blead, perldelta as PR22017 1.75 smoke report checks: testing win32 gcc failures 0.27 #22007 review updates and approve
4.25
2024/02/26 Monday 2.10 look over smoke reports, debug PERLIO=stdio failure on mac
3.48
2024/02/27 Tuesday 0.08 #22029 review and apply to blead 0.27 #22024 review and approve 0.33 #22026 review and approve 0.08 #22027 review and approve 0.10 #22028 review and approve 0.08 #22030 review and comment, conditionally approve 0.25 #22033 review, comments and approve 0.08 #22034 review and approve 0.17 #22035 review and comment
2.22
2024/02/28 Wednesday 0.38 github notifications 0.52 #22040 review discussion, research and comment 0.13 #22043 review and approve 0.12 #22044 review and approve 0.72 #22045 review, research, comment and approve 0.13 #22046 review, research and approve
3.55
2024/02/29 Thursday 0.15 #21966 review update and approve 1.18 #21877 debugging
1.46
Which I calculate is 55.79 hours.
Approximately 70 tickets were reviewed or worked on, and 5 patches were applied. ```
Published by Lee J on Monday 06 May 2024 14:39
The London Perl & Raku Workshop (LPW) will take place this year on Saturday 26th October and you are encouraged to submit your talk proposals now. The venue is in final stages of being confirmed - it will be in central London (UK).
We'd also like to announce our CFP. We welcome proposals relating to Perl 5, Raku, other languages, and supporting technologies. We may even have space for a couple of talks entirely tangential as we are close to finalising the venue (very central London) and should have room for two tracks.
Talks may be long (40mins), short (20 mins), or very short (aka lightning, 5 mins) but we would prefer talks to be on the shorter side and will likely prioritise 20min talks. We would also be pleased to accept proposals for tutorials and discussions. The deadline for submissions is 30th September.
We would really like to have more first time speakers. If you’d like help with a talk proposal, and/or the talk itself, let us know - we’ve got people happy to be your talk buddy!
Register (it's free!) and submit your talk on the workshop site.
We would also like to make a call for sponsors - does your company want to support the workshop? By sponsoring LPW you can demonstrate your support for the Perl and/or Raku languages and nurture your relationship with the local developer community. Much more information can be found on the workshop site along with a sponsor prospectus.
As well as the benefits as listed on the aforementioned page, sponsors will all feature in blog posts, news posts, social media posts.
That starts right now, with our first sponsors who have already generously sponsored the workshop:
With thanks from The London Perl & Raku Workshop 2024 organising team.
Two easy tasks this week, with a common thread that things get easier if data is re-arranged. (1) Magic Number (2) Number Game
Musical reference: take your pick. Personally, I like the Joe South song.
Games People Play (Joe South, 1970)
Games People Play (Spinners, 1975)
Games People Play (Alan Parsons Project, 1980)
You are given two arrays of integers of the
same size, @x and @y.
Write a script to find the magic number that,
when added to each element of one of the arrays,
gives the second array.
Element order is not important.
@x = (3, 7, 5)
, @y = (9, 5, 7)
2
.@x = (3, 7, 5) + 2 2 2 @y = (5, 9, 7)
@x = (1, 2, 1)
, @y = (5, 4, 4)
3
@x = (2)
, @y = (5)
3
If the arrays were sorted, it would be obvious that the magic number is the difference between any pair. So let's find the lowest number in each array and find the difference.
sub magicNumber($x, $y)
{
use List::Util qw/min/;
return min($y->@*) - min($x->@*);
}
That's pretty lazy. I really should be validating that the inputs are the same length, and that the magic number works for mapping all elements of $x
to $y
. Let's add a validate
function
sub validate($x, $y, $magic) { ... }
...
return validate($x, $y, min($y->@*) - min($x->@*));
...
validate
will return either $magic
, or undef
if there is no number that works.
If $magic
really is magic, then it will be true that adding it to every element of $x
will create an element of $y
. Let's do that.
my %should_be_y;
$should_be_y{ $_ + $magic } = $_ for $x->@*;
Now, it should be true that all the keys of %should_be_y
are elements of $y
. If we delete all $y
keys, then %should_be_y
would be left empty.
delete $should_be_y{$_} for $y->@*;
return scalar(%should_be_y) == 0 ? $magic : undef;
Here's the whole validate
function:
sub validate($x, $y, $magic)
{
return undef if $x->$#* != $y->$#*;
my %should_be_y;
$should_be_y{$_ + $magic} = $_ for $x->@*;
delete $should_be_y{$_} for $y->@*;
return scalar(%should_be_y) == 0 ? $magic : undef;
}
Perl notes:
sub mn :prototype(\@@) {
my @x = @{shift @_};
my @y = @_;
}
$y->@*
) because I find it readable; the other way to get the full array would be to use a prefix sigil (@{$y}
). Notice that the last index of an array is available as $x->$#*
and $y->$#*
.You are given an array of integers, @ints,
with an even number of elements.
Write a script to create a new array made up
of elements of the given array. Pick the two
smallest integers and add them to new array in
decreasing order, i.e. high to low. Keep doing
this until the given array is empty.
@ints = (2, 5, 3, 4)
(3, 2, 5, 4)
(2, 3)
and push it to the new array (3, 2)
(4, 5)
and push it to the new array (5, 4)
@ints = (9, 4, 1, 3, 6, 4, 6, 1)
(1, 1, 4, 3, 6, 4, 9, 6)
@ints = (1, 2, 2, 3)
(2, 1, 3, 2)
A bit of reflection reveals that all we're really doing here is swapping pairs of the sorted array. We could literally follow the instructions of the task (find the lowest numbers, swap them, push them onto an array), but maybe we can do something that exploits Perl features better.
And by better, I mean using array operations.
If we had the @ints
array sorted, then we would be selecting its elements in pairs: (1,0), (3,2), (5,4), etc.
If we had that list of indexes (1,0,3,2,5,4,...), then we could take a slice of the sorted array. So how could we generate the list of indexes?
That's odd and even indexes, which means pairs of 2*n+1 and 2*n. The range of numbers we need is half the length of the array, which is $#ints/2
. We can map that range into pairs of corresponding odd and even numbers. The map
operator can map each of its inputs to multiple output values, a useful behavior.
my @choose = map { 2 * $_ +1, 2*$_ } 0 .. ($#ints / 2)
Now all that remains is to use that generated array to take a slice of the sorted array.
@ints = sort { $a <=> $b } @ints;
return @ints[ @choose ];
We can elide the temporary variables, at the cost of readability.
sub game(@ints)
{
return [ (sort { $a <=> $b } @ints)[ map { 2*$_+1, 2*$_ } 0 .. $#ints/2 ] ];
}
Here we are returning a reference to the result instead of a list, for two reasons: (1) it avoids making a copy of the array as it's passed back up the stack, and (2) it's easier to use the function in a unit test.
sub runTest
{
use Test2::V0;
is( game(2,5,3,4), [3,2,5,4], "Example 1");
is( game(9,4,1,3,6,4,6,1), [1,1,4,3,6,4,9,6], "Example 2");
is( game(1,2,2,3), [2,1,3,2], "Example 3");
done_testing;
}
Finished code is on GitHub
Published by Gabor Szabo on Monday 06 May 2024 10:11
Originally published at Perl Weekly 667
Hi there!
Last week Mohammed already mentioned the LPW, now they have a Call For Papers and Sponsors. I am glad they write on bpo, but I also wonder, do they publish the CFP on other web sites as well. e.g. DEV.to?
I don't have a lot of time dealing with Perl these days, but I looked at the recent report of CPAN Digger and I see there are still quite a few CPAN packages that do not link to their public Version Control System (VCS). If you have some spare time maybe you could check out the modules in the VCS column and ask the author to add the appropriate fields so it will be easier for others to find the git repository.
Today is the Holocaust memorial day in Israel. I assume most of the readers of the Perl Weekly know what it is about, but I am surprised how many people in the world have never heard the word or don't know what it is about. I spend the day partially by watching interviews and lectures. I listed some of them on my site: Holocaust memorial day in Israel in 2024.
I also wrote an article titled Rafah and the humanitarian aid for Gaza. If you'd like to read more about the topic from me, you can register to my newsletter.
Unfortunately I need to deal with this quite a lot instead of sending Pull-Requests.
You, enjoy your week!
--
Your editor: Gabor Szabo.
The new Carp::Object module is an object-oriented replacement for Carp or Carp::Clan. What is the point? Well, there are some motivations.
Upgrading the OS and Perl can go terribly, but one has to do it anyway and it is probably better to do it frequently than rarely.
Apparently Ricardo was also into upgrading servers.
The Weekly Challenge by Mohammad Sajid Anwar will help you step out of your comfort-zone. We pick one champion at the end of the month from among all of the contributors during the month.
Welcome to a new week with a couple of fun tasks "Magic Number" and "Number Game". If you are new to the weekly challenge then why not join us and have fun every week. For more information, please read the FAQ.
Enjoy a quick recap of last week's contributions by Team PWC dealing with the "Product Sign" and "Line Counts" tasks in Perl and Raku. You will find plenty of solutions to keep you busy.
Usual dose of Raku magics for all of us. Plenty to keep you busy.
Bob is back with yet another Perl power sharing tri-valued operator. Thanks for sharing the knowledge with us.
Perl lacks handy functions as compare to Raku but you can come up with quick one in no time as Jaldhar has shared in this post. You really don't want to miss it.
Clever use of 'reduce' of List::Util to get the job done. The task analysis is worth checking out.
We got bonus one-liner in Raku as well as modular functional solution. Highly recommended.
No gimmicks for the Line Counts task. Just straight forward approach both in Perl and Raku. Thanks for sharing knowledge with us.
Love how the weekly challenge is inspiring to get smart and clever one-liner in Perl. Great work, keep it up.
Master of Perl one-liners in the Team PWC is keep the tradition alive and sharing another special one-liner. Highly recommended.
Use of lambda in Python solution is really cool. I love it. Well done and keep it up.
Peter sharing multiple approaches to get the desired result. You really don't want to skip it.
Perl special variables in action. It would catch your attention, I am confident about it.
Using the method signature of latest Perl makes the code looks elegant, very impressive, keep it up.
PostScript has always amazed me the most with all the unique syntax. It is always fun to read the code. Thank you for keeping us entertained every week,
Great CPAN modules released last week;
You joined the Perl Weekly to get weekly e-mails about the Perl programming language and related topics.
Want to see more? See the archives of all the issues.
Not yet subscribed to the newsletter? Join us free of charge!
(C) Copyright Gabor Szabo
The articles are copyright the respective authors.
Published by jkeenan on Sunday 05 May 2024 21:22
POSIX/t/wrappers.t: One-character typo
Published by Unknown on Saturday 04 May 2024 22:46
Published by haarg on Saturday 04 May 2024 20:05
remove underscore from VERSION in podlators When using versions with underscores, best practice is to remove the underscore on a later line, to allow using the version as a number when accessing the variable directly.
Published by tonycoz on Saturday 04 May 2024 17:39
hints/netbsd.sh: prevent noise when checking for --whole-archive https://www.nntp.perl.org/group/perl.perl5.porters/2024/04/msg268141.html
Published by jkeenan on Friday 03 May 2024 22:19
Update location of further documentation Fixes GH #22181; thanks to djerius.
Published by Makoto Nozaki on Friday 03 May 2024 19:49
I am pleased to announce that The Perl and Raku Foundation sponsored the Perl Toolchain Summit 2024 as a Platinum Sponsor.
The Perl Toolchain Summit (PTS) is an annual event where they bring together the volunteers who work on the tools and modules at the heart of Perl and the CPAN ecosystem. The PTS gives them 4 days to work together on these systems, with all their fellow volunteers to hand.
The event successfully concluded in Lisbon, Portugal at the end of April 2024.
If you or your company is willing to help the future PTS events, you can get in touch with the PTS team. Alternatively, you can make a donation to The Perl and Raku Foundation, which is a 501(c)(3) organization.
Published by perlancar on Wednesday 01 May 2024 02:38
dist | author | abstract | date |
---|---|---|---|
AI-Ollama-Client | CORION | Client for AI::Ollama | 2024-04-05T09:15:33 |
Acme-CPANModules-BPOM-FoodRegistration | PERLANCAR | List of modules and utilities related to Food Registration at BPOM | 2024-04-27T00:06:16 |
Acme-CPANModules-JSONVariants | PERLANCAR | List of JSON variants/extensions | 2024-04-29T00:05:46 |
Alien-NLOpt | DJERIUS | Build and Install the NLOpt library | 2024-04-28T00:59:11 |
Alien-onnxruntime | EGOR | Discover or download and install onnxruntime (ONNX Runtime is a cross-platform inference and training machine-learning accelerator.) | 2024-04-17T22:03:45 |
AnyEvent-I3X-Workspace-OnDemand | WATERKIP | An I3 workspace loader | 2024-04-12T18:33:21 |
App-papersway | SPWHITTON | PaperWM-like window management for Sway/i3wm | 2024-04-12T08:18:00 |
App-sort_by_comparer | PERLANCAR | Sort lines of text by a Comparer module | 2024-04-16T00:06:00 |
App-sort_by_example | PERLANCAR | Sort lines of text by example | 2024-04-20T00:05:10 |
App-sort_by_sorter | PERLANCAR | Sort lines of text by a Sorter module | 2024-04-17T00:05:42 |
App-sort_by_sortkey | PERLANCAR | Sort lines of text by a SortKey module | 2024-04-24T00:06:38 |
Arithmetic-PaperAndPencil | JFORGET | simulating paper and pencil techniques for basic arithmetic operations | 2024-04-22T19:57:44 |
Bencher-Scenario-ExceptionHandling | PERLANCAR | Benchmark various ways to do exception handling in Perl | 2024-04-13T00:05:36 |
CPAN-Requirements-Dynamic | LEONT | Dynamic prerequisites in meta files | 2024-04-27T15:17:57 |
CSAF | GDT | Common Security Advisory Framework | 2024-04-23T21:49:42 |
CXC-DB-DDL | DJERIUS | DDL for table creation, based on SQL::Translator::Schema | 2024-04-04T16:24:13 |
Captcha-Stateless-Text | HIGHTOWE | stateless, text-based CAPTCHAs | 2024-04-17T21:19:21 |
Carp-Object | DAMI | a replacement for Carp or Carp::Clan, object-oriented | 2024-04-28T17:58:22 |
Carp-Patch-OutputToBrowser | PERLANCAR | Output stacktrace to browser as HTML instead of returning it | 2024-04-25T00:05:19 |
Catalyst-Plugin-Flash | ARISTOTLE | put values on the stash of the next request | 2024-04-09T05:06:19 |
Comparer-date_in_text | PERLANCAR | Compare date found in text (or text asciibetically, if no date is found) | 2024-04-18T00:05:43 |
Crypt-Passphrase-Bcrypt-Compat | LEONT | A bcrypt encoder for Crypt::Passphrase | 2024-04-08T14:24:10 |
DBD-Mock-Session-GenerateFixtures | UXYZAB | When a real DBI database handle ($dbh) is provided, the module generates DBD::Mock::Session data. Otherwise, it returns a DBD::Mock::Session object populated with generated data. This not a part form DBD::Mock::Session distribution just a wrapper around it. | 2024-04-29T18:25:02 |
Data-Dumper-UnDumper | BIGPRESH | load Data::Dumper output, including self-references | 2024-04-25T21:42:30 |
Data-MiniDumpX | PERLANCAR | A simplistic data structure dumper (demo for Plugin::System) | 2024-04-14T00:06:13 |
DateTime-Format-PDF | SKIM | PDF DateTime Parser and Formatter. | 2024-04-01T09:23:07 |
Devel-Confess-Patch-UseDataDumpHTMLCollapsible | PERLANCAR | Use Data::Dump::HTML::Collapsible to stringify reference | 2024-04-26T00:05:16 |
Devel-Confess-Patch-UseDataDumpHTMLPopUp | PERLANCAR | Use Data::Dump::HTML::PopUp to stringify reference | 2024-04-28T00:06:05 |
Dist-Build | LEONT | A modern module builder, author tools not included! | 2024-04-26T10:50:10 |
Dist-Zilla-Plugin-DistBuild | LEONT | Build a Build.PL that uses Dist::Build | 2024-04-26T10:55:35 |
Dist-Zilla-Plugin-DynamicPrereqs-Meta | LEONT | Add dynamic prereqs to to the metadata in our Dist::Zilla build | 2024-04-27T15:50:03 |
ExtUtils-Builder | LEONT | An overview of the foundations of the ExtUtils::Builder Plan framework | 2024-04-25T12:14:45 |
ExtUtils-Builder-Compiler | LEONT | Portable compilation | 2024-04-25T13:18:11 |
JSON-Ordered-Conditional | LNATION | A conditional language within an ordered JSON struct | 2024-04-06T06:47:37 |
JSON-ToHTML | ARISTOTLE | render JSON-based Perl datastructures as HTML tables | 2024-04-09T04:28:11 |
Knowledge | RSPIER | a great new dist | 2024-04-27T11:13:53 |
Log-Any-Simple | MATHIAS | A very thin wrapper around Log::Any, using a functional interface that dies automatically when you log above a given level. | 2024-04-24T19:51:03 |
Mo-utils-Country | SKIM | Mo country utilities. | 2024-04-11T13:41:33 |
Mo-utils-Time | SKIM | Mo time utilities. | 2024-04-12T14:28:06 |
Mo-utils-TimeZone | SKIM | Mo timezone utilities. | 2024-04-03T16:34:52 |
Mojolicious-Plugin-Authentication-OIDC | TYRRMINAL | OpenID Connect implementation integrated into Mojolicious | 2024-04-25T19:27:09 |
Mojolicious-Plugin-Cron-Scheduler | TYRRMINAL | Mojolicious Plugin that wraps Mojolicious::Plugin::Cron for job configurability | 2024-04-16T11:48:54 |
Mojolicious-Plugin-Migration-Sqitch | TYRRMINAL | Run Sqitch database migrations from a Mojo app | 2024-04-30T15:37:52 |
Mojolicious-Plugin-Module-Loader | TYRRMINAL | Automatically load mojolicious namespaces | 2024-04-19T14:09:36 |
Mojolicious-Plugin-ORM-DBIx | TYRRMINAL | Easily load and access DBIx::Class functionality in Mojolicious apps | 2024-04-03T13:32:06 |
Mojolicious-Plugin-SendEmail | TYRRMINAL | Easily send emails from Mojolicious applications | 2024-04-01T20:40:24 |
Mojolicious-Plugin-Sessionless | TYRRMINAL | Installs noop handlers to disable Mojolicious sessions | 2024-04-16T12:45:37 |
MooX-Pack | LNATION | The great new MooX::Pack! | 2024-04-20T01:52:17 |
Net-Async-OpenExchRates | VNEALV | Interaction with OpenExchangeRates API | 2024-04-20T11:46:28 |
Net-EPP-Server | GBROWN | A simple EPP server implementation. | 2024-04-08T09:38:21 |
Number-Iterator | LNATION | The great new Number::Iterator! | 2024-04-18T19:45:31 |
Parallel-TaskExecutor | MATHIAS | Cross-platform executor for parallel tasks executed in forked processes | 2024-04-13T20:02:27 |
Plack-App-Login-Request | SKIM | Plack application for request of login information. | 2024-04-29T14:23:02 |
Sah-SchemaBundle-Business-ID-BCA | PERLANCAR | Sah schemas related to BCA (Bank Central Asia) bank | 2024-04-23T00:05:53 |
Sah-SchemaBundle-Business-ID-Mandiri | PERLANCAR | Sah schemas related to Mandiri bank | 2024-04-30T00:05:43 |
Sah-SchemaBundle-Comparer | PERLANCAR | Sah schemas related to Comparer | 2024-04-21T00:05:30 |
Sah-SchemaBundle-Path | PERLANCAR | Schemas related to filesystem path | 2024-04-01T00:06:15 |
Sah-SchemaBundle-Perl | PERLANCAR | Sah schemas related to Perl | 2024-04-02T00:05:40 |
Sah-SchemaBundle-SortKey | PERLANCAR | Sah schemas related to SortKey | 2024-04-22T00:06:02 |
Sah-SchemaBundle-Sorter | PERLANCAR | Sah schemas related to Sorter | 2024-04-03T00:14:57 |
Sah-Schemas-Sorter | PERLANCAR | Sah schemas related to Sorter | 2024-04-03T00:05:43 |
Seven | LNATION | The great new Seven! | 2024-04-13T03:30:11 |
Sort-Key-SortKey | PERLANCAR | Thin wrapper for Sort::Key to easily use SortKey::* | 2024-04-04T00:05:05 |
SortExample-Color-Rainbow-EN | PERLANCAR | Ordered list of names of colors in the rainbow, in English | 2024-04-05T00:06:12 |
SortKey-Num-pattern_count | PERLANCAR | Number of occurrences of string/regexp pattern as sort key | 2024-04-06T00:05:41 |
SortKey-Num-similarity | PERLANCAR | Similarity to a reference string as sort key | 2024-04-08T00:05:21 |
SortKey-date_in_text | PERLANCAR | Date found in text as sort key | 2024-04-19T00:05:23 |
SortSpec | PERLANCAR | Specification of sort specification | 2024-04-09T00:05:37 |
SortSpec-Perl-CPAN-ChangesGroup-PERLANCAR | PERLANCAR | Specification to sort changes group heading PERLANCAR-style | 2024-04-10T00:05:24 |
Sorter-from_comparer | PERLANCAR | Sort by comparer generated by a Comparer:: module | 2024-04-11T00:05:17 |
Sorter-from_sortkey | PERLANCAR | Sort by keys generated by a SortKey:: module | 2024-04-12T00:05:58 |
Sqids | MYSOCIETY | generate short unique identifiers from numbers | 2024-04-06T10:43:27 |
TableData-Business-ID-BPOM-FoodAdditive | PERLANCAR | Food additives in BPOM | 2024-04-10T11:10:00 |
Tags-HTML-Image | SKIM | Tags helper class for image presentation. | 2024-04-20T13:32:39 |
Tags-HTML-Login-Request | SKIM | Tags helper for login request. | 2024-04-29T11:23:37 |
Test2-Tools-MIDI | JMATES | test MIDI file contents | 2024-04-09T23:42:34 |
Tiny-Prof | TIMKA | Perl profiling made simple to use. | 2024-04-26T07:19:38 |
Web-Async | TEAM | Future-based web+HTTP handling | 2024-04-23T16:50:24 |
YAML-Ordered-Conditional | LNATION | A conditional language within an ordered YAML struct | 2024-04-06T06:05:51 |
kraken | PHILIPPE | api.kraken.com connector | 2024-04-05T09:11:35 |
papersway | SPWHITTON | PaperWM-like window management for Sway/i3wm | 2024-04-12T07:52:39 |
Number of new CPAN distributions this period: 81
Number of authors releasing new CPAN distributions this period: 26
Authors by number of new CPAN distributions this period:
No | Author | Distributions |
---|---|---|
1 | PERLANCAR | 30 |
2 | TYRRMINAL | 7 |
3 | LEONT | 7 |
4 | SKIM | 7 |
5 | LNATION | 5 |
6 | MATHIAS | 2 |
7 | SPWHITTON | 2 |
8 | DJERIUS | 2 |
9 | ARISTOTLE | 2 |
10 | PHILIPPE | 1 |
11 | JFORGET | 1 |
12 | VNEALV | 1 |
13 | RSPIER | 1 |
14 | UXYZAB | 1 |
15 | WATERKIP | 1 |
16 | GBROWN | 1 |
17 | CORION | 1 |
18 | EGOR | 1 |
19 | TIMKA | 1 |
20 | TEAM | 1 |
21 | BIGPRESH | 1 |
22 | HIGHTOWE | 1 |
23 | DAMI | 1 |
24 | MYSOCIETY | 1 |
25 | JMATES | 1 |
26 | GDT | 1 |
Welcome to “What’s new on CPAN”, a curated look at last month’s new CPAN uploads for your reading and programming pleasure. Enjoy!
I've just returned from two weeks of traveling from Lisbon through the south of Spain to Barcelona. It's a beautiful country. I wish that for just one time you could stand inside my shoes. The trip was a bit too rushed (Lisbon: check; Cordoba: check; Grenada: check, Seville: check, ...). I could happily return to any of them for a week.
But the best part is coming home to a backlog of Weekly Challenges!
You are given an array of @ints. Write a script
to find the sign of product of all integers in
the given array. The sign is 1 if the product
is positive, -1 if the product is negative and
0 if the product is zero.
@ints = (-1, -2, -3, -4, 3, 2, 1)
1
@ints = (1, 2, 0, -2, -1)
0
@ints = (-1, -1, 1, -1, 2)
-1
Simple problem, but there several ways to approach it. We could do as the examples suggest and multiply it out. No, I do not feel that good when I see the integer overflow that could occur.
Because math, we know that it will be zero if any number in the list is zero, and it will be negative if there are an odd number of negative elements in the list. We could walk over the list, counting negatives and bailing out if we find a zero.
But I just want to be on the side that's winning, and there's Perl, offering up the tri-valued <=>
operator. Comparing a number to 0 will hand us -1, 0, or 1 -- just what we need.
sub prodSign(@ints)
{
my $sign = 1;
while ( $sign && defined(my $n = shift @ints) )
{
$sign *= ($n <=> 0);
}
return $sign;
}
The while
loop is a cute Perl idiom for traversing a list. We eat up the first element in each iteration; it will eventually return undef
when nothing is left.
The first condition of the while
loop ($sign
) will end the loop if the product becomes zero -- a possible optimization. You say you lost your faith that there would be premature optimization? You had no faith to lose, and you know it.
You are given a string, $str, and a 26-items
array @widths containing the width of each
character from a to z. Write a script to find
the number of lines and the width of the last
line needed to display the given string, assuming
you can only fit 100 width units on a line.
$str = "abcdefghijklmnopqrstuvwxyz"
@widths = (10,10,10,10,10,10,10,10,10,10,10,10,10,
10,10,10,10,10,10,10,10,10,10,10,10,10)
(3, 60)
$str = "bbbcccdddaaa"
@widths = (4,10,10,10,10,10,10,10,10,10,10,10,10,
10,10,10,10,10,10,10,10,10,10,10,10,10)
(2, 4)
Some of these characters are going to have to move to other lines. And now I know you're dissatisfied with your position and your place, but don't you understand that's not my problem? The only problem is to figure out how long the last line is.
We don't even care what the lines actually contain. We can just replace every character with its width, and find groups of 100 or less until we're done.
So let's Perl it up. First, some minimal data integrity. Let's make sure our string really only contains valid characters by converting to lowercase, and deleting any characters that aren't 'a' through 'z'.
$str = lc $str;
$str =~ s/[^a-z]//g;
Then, we have a couple of things that are constants: the line width of 100, and the beginning of the alphabet.
use constant { MAXLINE => 100,
ORD_A => ord('a')
};
We're taking the easy way out here, assuming ASCII characters. The ord
function gives us the numeric value of a character (although everybody knows that 'a' is 0x61 —- highway 61 revisited?), which will give us offsets into the @widths
table. We could be a little more robust by turning the @widths
table into a hash lookup for a
through z
, but not today. You say I let you down; you know it's not like that. You know as well as me you'd rather see it optimized.
To replace the characters with their widths, we'll split the string into individual characters and replace them with a width from the @widths
array.
my @cw = map { $widths[ ord($_) - ORD_A ] } split(//, $str);
Now we consume that list of widths, starting a new line every time we reach 100.
my $lineCount = 1;
my $width = 0;
while ( defined(my $w = shift @cw) )
{
if ( $width + $w <= MAXLINE )
{
$width += $w;
}
else
{
$width = $w;
$lineCount++;
}
}
return [ $lineCount, $width ];
Published by Ted James on Monday 29 April 2024 07:12
Published by DragosTrif on Monday 29 April 2024 06:43
A while ago I discovered DBD::Mock
and it looked like a great tool to use in Perl unit tests. However the challenge of generating the fixtures was not always easy.
In order to solve this issue I have put together a small library that should help generate the fixture data needed.
At the core this very simple, I have mocked DBI
subs in order to capture the necessary information and stored it into a file:
The first step was to generate an override object and store it on $self
:
package DBD::Mock::Session::GenerateFixtures;
use Sub::Override;
...
our $override = Sub::Override->new();
sub new {
$self->{override} = $override;
}
Then we can use this to mock DBI
code like in the following example:
sub _override_dbi_execute {
my $self = shift;
my $dbi_execute = shift;
my $orig_execute = \&$dbi_execute;
$self->get_override_object()->replace(
$dbi_execute,
sub {
my ($sth, @args) = @_;
my $sql = $sth->{Statement};
my $col_names = $sth->{NAME};
my $retval = $orig_execute->($sth, @args);
my $rows = $sth->rows();
my $query_data = {
statement => $sql,
bound_params => \@args,
col_names => $col_names,
};
my $result = [];
if ($rows > 0) {
foreach my $row (1 .. $rows) {
push @{$result}, [];
}
$query_data->{results} = $result;
}
$query_data->{bound_params} = $self->{bind_params}
if scalar @{$self->{bind_params}} > 0;
push @{$self->{result}}, $query_data;
$self->_write_to_file();
$self->{bind_params} = [];
$self->{sth} = $sth;
return $retval;
}
);
return $self;
}
This code works for do
or prepare
and execute
when you are trying to mock insert, update or delete statements like is this example:
subtest 'upsert generate mock data' => sub {
my $dbh = db_handle('test.db');
build_tests_db($dbh);
populate_test_db($dbh);
my $obj = DBD::Mock::Session::GenerateFixtures->new({dbh => $dbh});
$dbh = $obj->get_dbh();
my $sql_license = <<"SQL";
INSERT INTO licenses (name, allows_commercial) VALUES ( ?, ? )
SQL
chomp $sql_license;
my $r = $dbh->do($sql_license, undef, 'test_license', 'no');
is($r, 1, 'one row inserted is ok');
my $update_sql = 'update licenses set allows_commercial = ? where id > ?';
$r = $dbh->do($update_sql, undef, 'yes', '3');
is($r, 2, 'update works ok');
$r = $dbh->do($update_sql, undef, 'yes', '100');
is($r, '0E0', 'now rows updated');
my $delete_sql = 'DELETE FROM licenses WHERE id = ?';
my $sth = $dbh->prepare($delete_sql);
$sth->execute(3);
is($sth->rows(), 1, 'delete with prepare and execute is ok');
$obj->restore_all();
$dbh->disconnect();
};
The the following data is stored in a Json
file:
[
{
"statement" : "INSERT INTO licenses (name, allows_commercial) VALUES ( ?, ? )",
"results" : [
[]
],
"col_names" : [],
"bound_params" : [
"test_license",
"no"
]
},
{
"bound_params" : [
"yes",
"3"
],
"statement" : "update licenses set allows_commercial = ? where id > ?",
"col_names" : [],
"results" : [
[],
[]
]
},
{
"col_names" : [],
"statement" : "update licenses set allows_commercial = ? where id > ?",
"bound_params" : [
"yes",
"100"
]
},
{
"statement" : "DELETE FROM licenses WHERE id = ?",
"col_names" : [],
"results" : [
[]
],
"bound_params" : [
3
]
}
]
Please observe how the results key is populate with an empty array for each row touched by our statement and it is ready to be used when a DBD::Mock::Session object is built.
For select statements you need a extra layer of mocking in order to store the exact values a select could use.
Here is how the mock for fetchrow_hashref
looks like:
sub _override_dbi_fetchrow_hashref {
my $self = shift;
my $fetchrow_hashref = shift;
my $orig_selectrow_hashref = \&$fetchrow_hashref;
$self->get_override_object()->replace(
$fetchrow_hashref,
sub {
my ($sth) = @_;
my $retval = $orig_selectrow_hashref->($sth);
if (ref $retval) {
my $query_results = $self->_set_hashref_response($sth, $retval);
push @{$self->{result}->[-1]->{results}}, $query_results;
$self->_write_to_file();
}
return $retval;
}
);
return $self;
}
This produces the following data by pushing the each row in the result key:
[
{
"statement" : "SELECT * FROM media_types WHERE id IN(?,?)",
"col_names" : [
"id",
"media_type"
],
"results" : [
[
1,
"video"
],
[
2,
"audio"
]
],
"bound_params" : [
2,
1
]
}
]
Form this point one I just need to make sure that every way in which DBI lets you get the data is covered by my code. In the end I end it mocking the following subs:
Readonly::Hash my %MOCKED_DBI_METHODS => (
execute => 'DBI::st::execute',
bind_param => 'DBI::st::bind_param',
fetchrow_hashref => 'DBI::st::fetchrow_hashref',
fetchrow_arrayref => 'DBI::st::fetchrow_arrayref',
fetchrow_array => 'DBI::st::fetchrow_array',
selectall_arrayref => 'DBI::db::selectall_arrayref',
selectall_hashref => 'DBI::db::selectall_hashref',
selectcol_arrayref => 'DBI::db::selectcol_arrayref',
selectrow_array => 'DBI::db::selectrow_array',
selectrow_arrayref => 'DBI::db::selectrow_arrayref',
selectrow_hashref => 'DBI::db::selectrow_hashref',
);
If you want to give this a try you can get the full code from this url:
DBD-Fixtures
Published by Unknown on Sunday 28 April 2024 09:07
Published by Unknown on Sunday 28 April 2024 09:05
This is the weekly favourites list of CPAN distributions. Votes count: 75
Week's winner (+4): App::perlimports
Build date: 2024/04/28 07:04:22 GMT
Clicked for first time:
Increasing its reputation:
These are the five most rated questions at Stack Overflow last week.
Between brackets: [question score / answers count]
Build date: 2024-04-28 07:03:15 GMT
Published by Amber Krawczyk on Saturday 27 April 2024 11:36
We hope you are coming to [The Perl and Raku Conference[(https://tprc.us/) in Las Vegas June 24-28! Plans are underway for a wonderful TPRC. But a conference of this type is only possible because of volunteers who give their time and expertise to plan, promote, and execute every detail. We need volunteers! You may have already volunteered to speak at the conference; if so, wonderful! If you are not presenting (or even if you are), there are many ways to help. We need people to set up and take down, to run the registration desk, to serve as room monitors, to help record the talks, and to just be extra hands. If you can spare some of your time for the sake of the conference, please fill out a volunteer form at https://tprc.us/tprc-2024-las/volunteer/ . We also welcome spouses and friends of attendees who might be coming along to Las Vegas to share the experience. We are offering TPRC "companion" tickets, for access to the social parts of the conference (food, drink, parties) but not the technical. Volunteers of at least one complete day, who sign up before the conference, will have companion access "comped". If you have questions about volunteering, please contact our TPRC Volunteer Coordinator: Sarah Gray sarah.gray@pobox.com
Published by Saif Ahmed on Friday 26 April 2024 15:18
Another Grant Application from a key Raku develoer, Stefan Seifert. A member of the Raku Steering Council, Stefan is also an author of several Perl 5 modules including Inline::Python and (of course) Inline::Perl6. This Grant is to help advance AST or Abstract Syntax Tree. This is integral to Raku internals and allows designing and implementation of new language components, that can be converted into bytecode for execution by the interpreteter or "virtual machine" more easily that trying to rewrite the interpretter. Here is an excellent intro by Elizabeth Mattijsen
There is a grant called RakuAST granted to Johnathan Worthington that is still listed as running. Sadly Johnathan has moved on and is no longer actively developing the Rakudo core. However the goal of his grant is still worthy as it is one of the strategic initiatives providing numerous benefits to the language. I have in fact already taken over his work on RakuAST and over the last two years have pushed some 450+ commits which led to hundreds of spectests to pass. This work was done in my spare time which was possible because I had a good and reliable source of income and could at times sneak in some Raku work into my dayjob. I can no longer claim that Raku is in any way connected to my day job and time invested in Raku comes directly out of the pool that should ensure my financial future. In other words, there's a real cost for me and I'd like to ask for this to be offset by way of a grant.
This is mostly directly taken from the RakuAST grant proposal as the goal stays the same:
An AST can be thought of as a document object model for a programming language. The goal of RakuAST is to provide an AST that is part of the Raku language specification, and thus can be relied upon by the language user. Such an AST is a prerequisite for a useful implementation of macros that actually solve practical problems, but also offers further powerful opportunities for the module developer. For example:
RakuAST will also become the initial internal representation of Raku programs used by Rakudo itself. That in turn gives an opportunity to improve the compiler. The frontend compiler architecture of Rakudo has changed little in the last 10 years. Naturally, those working on it have learned a few things in that time, and implementing RakuAST provides a chance to fold those learnings into the compiler. Better static optimization, use of parallel processing in the compiler, and improvements to memory and time efficiency are all quite reasonable expectations. We have already seen that the better internal structure fixes a few long standing bugs incidentally. However, before many of those benefits can be realized, the work of designing and implementing RakuAST, such that the object model covers the entire semantic and declarational space of the language, must take place. This grant focuses on that work.
Considering the amount of work these items already will be, I would specifically exclude work targeted at synthetic AST generation, designs for new macros based on this AST, and anything else that is not strictly necessary to reach the goal of the RakuAST compiler frontend becoming the default.
For the test and spectest suites I would continue my tried and proven model of picking the next failing test file and making fixes until it passes. Based on current velocity this will take around 6 months. However there's hope that some community members will return from their side projects and chime in.
I have been involved in Rakudo development since 2014 when I started development of Inline::Perl5 which brings full two-way interoperability between Raku and Perl. Since then I have helped with every major effort in Rakudo core development like the Great List Refactor, the new dispatch mechanism and full support for unsigned native integers. I have fixed hundreds of bugs in MoarVM including garbage collection issues, race conditions and bugs in the specializer. I have made NativeCall several orders of magnitude faster by writing a special dispatcher and support for JIT compiling native calls. I replaced a slow and memory hungry MAST step in the compilation process by writing bytecode directly, have written most of Rakudo's module loading and repository management code and in general have done everything I could to make Rakudo production worthy. I have also been a member of the Raku Steering Council since its inception.
Elizabeth Mattijsen, Geoffrey Broadwell, Nick Logan, Richard Hainsworth
At the Koha Hackfest I had several discussions with various colleagues about how to improve the way plugins and hooks are implemented in Koha. I have worked with and implemented various different systems in my ~25 years of Perl, so I have some opinions on this topic.
When you have some generic piece of code (eg a framework or a big application that will be used by different user groups (like Koha)), people will want to add custom logic to it. But this custom logic will probably not make sense to every user. And you probably don't want all of these weird adaptions in the core code. So you allow users to write their weird adaptions in Plugins, which will be called via Hooks in the core code base. This patter is used by a lot of software, from eg mod_perl/Apache, Media Players to JavaScript frontend frameworks like Vue.
Generally, there are two kinds of Hook philosophies: Explicit Hooks, where you add explicit calls to the hook to the core code; and Implicit Hooks, where some magic is used to call Plugins.
Explicit Hooks are rather easy to understand and implement:
package MyApp::Model::SomeThing;
method create ($args) {
$self->call_hook("pre_create", $args);
my $item = $self->resultset("SomeThing")->create( $args );
$self->call_hook("post_create", $args, $item);
return $item;
}
So you have a method create
which takes some $args
. It first calls the pre_create
hook, which could munge the $args
. Then it does what the Core implementation wants to do (in this case, create a new item in the database). After that it calls the post_create
hook which could do further stuff, but now also has the freshly created database row available.
The big advantage of explicit hooks is that you can immediately see which hook is called when & where. The downside is of course that you have to pepper your code with a lot of explicit calls, which can be very verbose, especially once you add error handling and maybe a way for the hook to tell the core code to abort processing etc. Our nice, compact and easy to understand Perl code will end up looking like Go code (where you have to do error handling after each function call)
Implicit hooks are a bit more magic, because the usually do not need any adaptions to the core code:
package MyApp::Model::SomeThing;
method create ($args) {
my $item = $self->resultset("Foo")->create( $args );
return $item
}
There are lots of ways to implement the magic needed.
One well-known one is Object Orientation, where you can "just" provide a subclass which overrides the default method. Of course you will then have to re-implement the whole core method in your subclass, and figure out a way to tell the core system that it should actually use your subclass instead of the default one.
Moose allows for more fine-grained ways to override methods with it's method modifiers like before
, after
and around
. If you also add Roles to the mix (or got all in with Parametric Roles) you can build some very abstract base classes (similar to Interfaces in other languages) and leave the actual implementation as an exercise to the user...
Coincidentally, at the German Perl Workshop Ralf Schwab presented how they used AUTOLOAD
and a hierarchy of shadow classes to add a Plugin/Hook system to their Cosmo web shop (which seems to be also wildly installed and around for quite some time). (I haven't seen the talk, only the slides
I have some memories (not sure if fond or nightmarish) of a system I build between 1998 and 2004 which (ab)used the free access Perl provides to the symbol table to use some config data to dynamically generate classes, which could then later by subclassed for even more customization.
But whatever you use to implement them, the big disadvantage of Implicit Hooks is that it is rather hard to figure out when & why each piece of code is called. But to actually and properly use implicit hooks, you will also have to properly structure your code in your core classes into many small methods instead of big 100-line monsters, which also improves testabilty.
Generally, "it depends". But for Koha I think Explicit Hooks are better:
next
or SUPER
) might be a bit to much for some Plugin authors (who might be more on the librarian-who-can-code-a-bit side of the spectrum then on dev-who-happens-to-work-with-libraries)boring > magic
!Using implicit hooks could maybe make sense if Koha
around
in Moose, error handling, ...).An while it itches me in the fingers to do come up with such a smart system, I think currently dev time is better spend on other issues and improvements.
P.S.: I'm currently traveling trough Albania, so I might be slow to reply to any feedback.
Published by Unknown on Sunday 21 April 2024 13:58
Published on Friday 19 April 2024 07:00
Last week we (aka HKS3) attended the Koha Hackfest in Marseille, hosted by BibLibre. The hackfest is a yearly meeting of Koha developers and other interested parties, taking place since ~10 years in Marseille. For me, it was the first time!
git-bz
.--dbshell
to KTD for easy access to the DB shell.Thanks to BibLibre and Paul Poulain for organizing the event, and to all the attendees for making it such a wonderful 4 days!
Published by perlancar on Sunday 14 April 2024 00:11
dist | author | abstract | date |
---|---|---|---|
AI-Chat | BOD | Interact with AI Chat APIs | 2024-03-02T22:12:10 |
AI-Image | BOD | Generate images using OpenAI's DALL-E | 2024-03-06T23:01:10 |
Acme-CPANModules-LoadingModules | PERLANCAR | List of modules to load other Perl modules | 2024-03-01T00:06:07 |
Acme-CPANModules-LoremIpsum | PERLANCAR | List of modules related to "Lorem Ipsum", or lipsum, placeholder Latin text | 2024-03-02T00:05:10 |
Acme-CPANModules-OpeningFileInApp | PERLANCAR | List of modules to open a file with appropriate application | 2024-03-04T00:05:56 |
Acme-CPANModules-RandomText | PERLANCAR | List of modules for generating random (placeholder) text | 2024-03-05T00:05:27 |
Acme-TaintTest | SIDNEY | module for checking taint peculiarities on some CPAN testers | 2024-03-25T09:22:24 |
Alien-Pipx | CHRISARG | Provides the pipx Python Package Manager | 2024-03-09T13:19:11 |
Alien-Qhull | DJERIUS | Build and Install the Qhull library | 2024-03-06T18:15:57 |
Alien-SeqAlignment-MMseqs2 | CHRISARG | find, build and install the mmseqs2 tools | 2024-03-24T03:33:13 |
Alien-SeqAlignment-bowtie2 | CHRISARG | find, build and install the bowtie2 tools | 2024-03-19T12:31:34 |
Alien-SeqAlignment-cutadapt | CHRISARG | Provide the cutadapt utility for eliminating polyA tails through pipx | 2024-03-09T04:49:02 |
Alien-SeqAlignment-hmmer3 | CHRISARG | find, build and install the hmmer3 tools | 2024-03-22T03:29:12 |
Alien-SeqAlignment-last | CHRISARG | find, build and install the last tools | 2024-03-16T21:16:36 |
Alien-SeqAlignment-minimap2 | CHRISARG | A Perl wrapper for the minimap2 binary executables | 2024-03-23T00:58:56 |
Alien-pipx | CHRISARG | Provides the pipx Python Package Manager | 2024-03-08T20:39:35 |
Amazon-Sites | DAVECROSS | A class to represent Amazon sites | 2024-03-20T16:18:39 |
App-BPOMUtils-RPO-Ingredients | PERLANCAR | Group ingredients suitable for food label | 2024-03-10T00:05:30 |
App-CSVUtils-csv_mix_formulas | PERLANCAR | Mix several formulas/recipes (lists of ingredients and their weights/volumes) into one, and output the combined formula | 2024-03-03T00:06:02 |
App-ComparerUtils | PERLANCAR | CLIs related to Comparer | 2024-03-06T00:05:48 |
App-DWG-Sort | SKIM | Tool to sort DWG files by version. | 2024-03-06T10:03:07 |
App-SortExampleUtils | PERLANCAR | CLIs related to SortExample | 2024-03-07T00:05:25 |
App-SortKeyUtils | PERLANCAR | CLIs related to SortKey | 2024-03-08T00:05:47 |
App-SortSpecUtils | PERLANCAR | CLIs related to SortSpec | 2024-03-09T00:05:07 |
App-SorterUtils | PERLANCAR | CLIs related to Sorter | 2024-03-11T00:05:26 |
App-SpreadsheetOpenUtils | PERLANCAR | Utilities related to Spreadsheet::Open | 2024-03-12T00:05:23 |
App-cat-v | UTASHIRO | cat-v command implementation | 2024-03-31T10:58:40 |
App-chartimes | TULAMILI | 2024-03-15T01:18:20 | |
App-colcount | TULAMILI | 各行について、カラムの数を数えたり、条件を満たすカラムの数を数えたりする。 | 2024-03-15T10:32:37 |
App-ctransition | TULAMILI | 入力の全ての文字に対して、次の文字は何であるかの回数の集計を、行列状に表示する。 | 2024-03-15T12:58:49 |
App-samelines | TULAMILI | 2024-03-14T07:49:49 | |
Bencher-Scenario-ListFlattenModules | PERLANCAR | Benchmark various List::Flatten implementaitons | 2024-03-13T00:05:28 |
Bencher-Scenarios-Text-Table-Sprintf | PERLANCAR | Scenarios for benchmarking Text::Table::Sprintf | 2024-03-14T00:05:21 |
Bio-SeqAlignment | CHRISARG | Aligning (and pseudo aligning) biological sequences | 2024-03-24T01:05:16 |
Business-Tax-US-Form_1040-Worksheets | JKEENAN | IRS Form 1040 worksheets calculations | 2024-03-20T19:16:50 |
CXC-Data-Visitor | DJERIUS | Invoke a callback on every element at every level of a data structure. | 2024-03-23T17:04:24 |
Carp-Patch-ExcludePackage | PERLANCAR | Exclude some packages from stack trace | 2024-03-15T00:06:01 |
Comparer-from_sortkey | PERLANCAR | Compare keys generated by a SortKey:: module | 2024-03-16T00:05:16 |
Compression-Util | TRIZEN | Implementation of various techniques used in data compression. | 2024-03-21T01:02:57 |
Data-Dump-HTML-Collapsible | PERLANCAR | Dump Perl data structures as HTML document with collapsible sections | 2024-03-08T08:22:33 |
Data-Dump-HTML-PopUp | PERLANCAR | Dump Perl data structures as HTML document with nested pop ups | 2024-03-18T13:24:01 |
Data-Dump-IfSmall | PERLANCAR | Like Data::Dump but reference with dump larger than a certain size will be dumped as something like 'LARGE:ARRAY(0x5636145ea5e8)' | 2024-03-18T00:06:06 |
Data-Dump-SkipObjects | PERLANCAR | Like Data::Dump but objects of some patterns are dumped tersely | 2024-03-19T00:05:05 |
Data-Navigation-Item | SKIM | Data object for navigation item. | 2024-03-04T11:53:10 |
Date-Holidays-Adapter-USA | GENE | Adapter for USA holidays | 2024-03-19T20:38:52 |
Date-Holidays-USA | GENE | Provides United States of America holidays | 2024-03-19T20:09:45 |
Devel-Confess-Patch-UseDataDumpIfSmall | PERLANCAR | Use Data::Dump::IfSmall format refs | 2024-03-20T00:05:59 |
Devel-Confess-Patch-UseDataDumpSkipObjects | PERLANCAR | Use Data::Dump::SkipObjects to stringify some objects | 2024-03-21T00:06:11 |
Dist-Zilla-Plugin-Sah-SchemaBundle | PERLANCAR | Plugin to use when building Sah-SchemaBundle-* distribution | 2024-03-22T00:05:48 |
Dist-Zilla-Role-GetDistFileURL | PERLANCAR | Get URL to a file inside a Perl distribution | 2024-03-23T00:05:56 |
GCC-Builtins | BLIAKO | access GCC compiler builtin functions via XS | 2024-03-19T13:31:21 |
ImgurAPI | DILLANBH | Imgur API client | 2024-03-20T03:11:21 |
ImgurAPI-Client | DILLANBH | 2024-03-20T03:31:39 | |
Intellexer-API | HAX | Perl API client for the Intellexer, a webservice that, "enables developers to embed Intellexer semantics products using XML or JSON." | 2024-03-04T02:34:33 |
LaTeX-Easy-Templates | BLIAKO | Easily format content into PDF/PS/DVI with LaTeX templates. | 2024-03-15T21:43:58 |
Markdown-Perl | MATHIAS | Very configurable Markdown processor written in pure Perl, supporting the CommonMark spec and many extensions | 2024-03-31T21:17:51 |
Module-Features-PluginSystem | PERLANCAR | Features of modules that generate text tables | 2024-03-25T00:05:33 |
Module-Pluggable-_ModuleFeatures | PERLANCAR | Features declaration for Module::Pluggable | 2024-03-26T00:05:20 |
Net-MailChimp | ARTHAS | Perl library with MINIMAL interface to use MailChimp API. | 2024-03-14T13:52:35 |
Net-OpenVPN-Manager | ATOY | Start OpenVPN Manager and return PSGI handler | 2024-03-08T18:07:11 |
Net-PaccoFacile | ARTHAS | Perl library with MINIMAL interface to use PaccoFacile API. | 2024-03-01T16:16:12 |
OpenAPI-PerlGenerator | CORION | create Perl client SDKs from OpenAPI specs | 2024-03-24T11:02:37 |
Plack-App-CPAN-Changes | SKIM | Plack application for CPAN::Changes object. | 2024-03-14T18:23:48 |
Plack-Middleware-Static-Precompressed | ARISTOTLE | serve a tree of static pre-compressed files | 2024-03-14T11:30:12 |
Plugin-System-_ModuleFeatures | PERLANCAR | Features declaration for Plugin::System | 2024-03-27T00:05:42 |
Qhull | DJERIUS | a really awesome library | 2024-03-05T20:37:59 |
Regexp-IntInequality | HAUKEX | generate regular expressions to match integers greater than / less than / etc. a value | 2024-03-08T17:59:24 |
Sah-SchemaBundle | PERLANCAR | Convention for Sah-SchemaBundle-* distribution | 2024-03-28T00:05:49 |
Sah-SchemaBundle-Array | PERLANCAR | Sah schemas related to array type | 2024-03-29T00:05:36 |
Sah-SchemaBundle-ArrayData | PERLANCAR | Sah schemas related to ArrayData | 2024-03-30T00:05:33 |
Sah-SchemaBundle-Binary | PERLANCAR | Sah schemas related to binary data | 2024-03-17T00:05:16 |
Sah-SchemaBundle-Bool | PERLANCAR | Sah schemas related to bool data type | 2024-03-24T00:05:52 |
Sah-SchemaBundle-BorderStyle | PERLANCAR | Sah schemas related to BorderStyle | 2024-03-31T00:05:05 |
Tags-HTML-CPAN-Changes | SKIM | Tags helper for CPAN::Changes object. | 2024-03-14T09:55:49 |
Template-Plugin-Package | PETDANCE | allow calling of class methods on arbitrary classes that do not accept the class name as their first argument. | 2024-03-12T04:32:11 |
Tk-FileBrowser | HANJE | Multi column file system explorer | 2024-03-29T21:22:08 |
WWW-Gemini | ANTONOV | 2024-03-11T02:51:49 | |
lib-root | HERNAN | find perl root and push lib modules path to @INC | 2024-03-30T17:27:02 |
Number of new CPAN distributions this period: 78
Number of authors releasing new CPAN distributions this period: 25
Authors by number of new CPAN distributions this period:
No | Author | Distributions |
---|---|---|
1 | PERLANCAR | 33 |
2 | CHRISARG | 9 |
3 | SKIM | 4 |
4 | TULAMILI | 4 |
5 | DJERIUS | 3 |
6 | BOD | 2 |
7 | ARTHAS | 2 |
8 | GENE | 2 |
9 | BLIAKO | 2 |
10 | DILLANBH | 2 |
11 | HERNAN | 1 |
12 | UTASHIRO | 1 |
13 | DAVECROSS | 1 |
14 | TRIZEN | 1 |
15 | ARISTOTLE | 1 |
16 | HAX | 1 |
17 | HANJE | 1 |
18 | JKEENAN | 1 |
19 | HAUKEX | 1 |
20 | MATHIAS | 1 |
21 | CORION | 1 |
22 | ATOY | 1 |
23 | PETDANCE | 1 |
24 | ANTONOV | 1 |
25 | SIDNEY | 1 |
Published by Blag aka Alvaro Tejada Galindo on Thursday 11 April 2024 17:59
Let’s continue our exploration of programming languages, with another well know language although not always loved, Perl.
Published by Ted James on Thursday 11 April 2024 16:43